package com.course.web.component.custom;

import com.course.domain.enums.TaskType;
import com.course.domain.enums.Week;
import com.course.web.biz.WebAgendaBiz;
import com.course.web.component.base.BaseEdit;
import com.course.web.component.base.BaseGrid;
import com.course.web.component.base.EditGrid;
import com.course.web.model.AgendaItemVM;
import com.course.web.model.AgendaWeekVM;
import com.course.web.view.StudentListView;
import com.google.common.collect.Lists;
import com.vaadin.data.Binder;
import com.vaadin.spring.annotation.SpringComponent;
import com.vaadin.spring.annotation.ViewScope;
import com.vaadin.ui.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.List;

/**
 * Created by Justin on 2017/6/13.
 */
@SpringComponent
@ViewScope
public class AgendaPlanGrid extends EditGrid<AgendaWeekVM> {

    static {
        List<Integer> hou = Lists.newArrayListWithCapacity(24);
        List<Integer> min = Lists.newArrayListWithCapacity(60);
        for (int i = 0; i < 24; i++) {
            hou.add(i);
        }
        for (int i = 0; i < 60; i++) {
            min.add(i);
        }
        HOU = hou;
        MIN = min;
    }

    private static final List<Integer> HOU;
    private static final List<Integer> MIN;

    private final WebAgendaBiz agendaBiz;
    private final BaseEdit<AgendaItemVM> timeEdit;

    public AgendaPlanGrid(WebAgendaBiz agendaBiz) {
        super(AgendaWeekVM.class);
        this.agendaBiz = agendaBiz;
        this.timeEdit = new BaseEdit<>(AgendaItemVM.class);
        initEdit(timeEdit);
    }

    @Override
    protected void doInitMenu(Layout menu) {
        Button back = new Button("返回");
        menu.addComponent(back);
        back.addClickListener(event -> getUI().getNavigator().navigateTo(StudentListView.NAME));
    }

    @Override
    protected void doInitGrid(BaseGrid<AgendaWeekVM> grid) {
        grid.addColumn(AgendaWeekVM::getWorkday, "平日时段", "workday");
        for (int i = 0; i < 7; i++) {
            int weekDay = i + 1;
            String id = String.valueOf(weekDay);
            grid.addColumn(week -> week.getItem(weekDay).getTitle(), Week.of(weekDay).getTitle(), id);
        }
        grid.addColumn(AgendaWeekVM::getWeekend, "周末时段", "weekend");
        grid.setHandler(this::edit);
    }

    @Override
    protected AgendaWeekVM doUpdate(AgendaWeekVM week) {
        if (week.getId() == 0) {
            return agendaBiz.createWeek(week);
        } else {
            return agendaBiz.updateWeek(week);
        }
    }

    private void initEdit(BaseEdit<AgendaItemVM> edit) {
        FormLayout form = new FormLayout();
        HorizontalLayout time = new HorizontalLayout();
        ComboBox<Integer> hou = new ComboBox<>(null, HOU);
        ComboBox<Integer> min = new ComboBox<>(null, MIN);
        Label split = new Label(":");

        form.addComponent(time);
        time.addComponent(hou);
        time.addComponent(split);
        time.addComponent(min);
        time.setCaption("开始时间");

        hou.setItemCaptionGenerator(value -> String.format("%02d", value));
        min.setItemCaptionGenerator(value -> String.format("%02d", value));
        hou.setWidth("100px");
        min.setWidth("100px");

        edit.initEdit(form);

        Binder<AgendaItemVM> binder = edit.binder();
        binder.forField(hou).bind(AgendaItemVM::getHH, AgendaItemVM::setHH);
        binder.forField(min).bind(AgendaItemVM::getMM, AgendaItemVM::setMM);
    }

    private void edit(AgendaWeekVM week, String id) {
        if (StringUtils.equals("workday", id)) {
            AgendaItemVM item = new AgendaItemVM(week.getPartIdx(), 0, TaskType.NONE);
            timeEdit.setHandler(data -> save(week, item, id));
            timeEdit.show(getUI(), item);
        } else if (StringUtils.equals("weekend", id)) {
            AgendaItemVM item = new AgendaItemVM(week.getPartIdx(), 8, TaskType.NONE);
            timeEdit.setHandler(data -> save(week, item, id));
            timeEdit.show(getUI(), item);
        } else if (NumberUtils.isDigits(id)) {
            AgendaItemVM item = week.getItem(NumberUtils.toInt(id));
            if (item.getType().getValue() != TaskType.NONE.getValue()) {
                timeEdit.setHandler(data -> save(week, data, id));
                timeEdit.show(getUI(), item);
            }
        }
    }

    private void save(AgendaWeekVM week, AgendaItemVM item, String id) {
        if (StringUtils.equals("workday", id)) {
            for (int weekDay = 1; weekDay <= 5; weekDay++) {
                AgendaItemVM itemDay = week.getItem(weekDay);
                itemDay.setTime(item.getTime());
                week.setItem(weekDay, itemDay);
            }
        } else if (StringUtils.equals("weekend", id)) {
            for (int weekDay = 6; weekDay <= 7; weekDay++) {
                AgendaItemVM itemDay = week.getItem(weekDay);
                itemDay.setTime(item.getTime());
                week.setItem(weekDay, itemDay);
            }
        } else {
            week.setItem(item.getWeekDay(), item);
        }
        update(week);
    }

    public void enter(int agendaId) {
        init(agendaBiz.findWeek(agendaId));
    }
}
